package com.zkjl.protect_business.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.zkjl.protect_business.common.BaseException;
import com.zkjl.protect_business.common.Status;
import com.zkjl.protect_business.entity.Notice;
import com.zkjl.protect_business.entity.PBFile;
import com.zkjl.protect_business.repository.NoticeRecordRepository;
import com.zkjl.protect_business.repository.NoticeRepository;
import com.zkjl.protect_business.repository.PBFileRepository;
import com.zkjl.protect_business.service.FileService;
import com.zkjl.protect_business.service.LogService;
import com.zkjl.protect_business.utils.MD5Util;
import com.zkjl.protect_business.utils.PDFUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.zkjl.protect_business.common.Consts.OPERATION_DOWNLOAD;

@Service
public class FileServiceImpl implements FileService {

    @Value(value = "${upload.path}")
    private String uploadPath;

    @Autowired
    PBFileRepository pbFileRepository;

    @Autowired
    NoticeRepository noticeRepository;
    @Autowired
    PBFileRepository fileRepository;

    @Autowired
    LogService logService;

    @Override
    public List<String> uploadImage(MultipartFile[] files) {
        File uploadDirectory = new File(uploadPath);
        if (uploadDirectory.exists()) {
            if (!uploadDirectory.isDirectory()) {
                uploadDirectory.delete();
            }
        } else {
            uploadDirectory.mkdir();
        }

        List<String> images = new ArrayList<>();

        //这里可以支持多文件上传
        if (files != null && files.length >= 1) {
            try {
                for (MultipartFile file : files) {

                    //验证文件是否已上传
                    String hash = MD5Util.digestHex(file);
                    PBFile byHash = pbFileRepository.findByHash(hash);
                    if (byHash != null) {
                        String name = byHash.getName();
                        images.add("/files/" + name);
                        continue;
                    }

                    String fileName = file.getOriginalFilename();
                    //判断是否有文件且是否为图片文件
                    if(fileName!=null && !"".equalsIgnoreCase(fileName.trim()) && isImageFile(fileName)) {

                        String simpleUUID = IdUtil.simpleUUID();
                        String name = simpleUUID + getFileType(fileName);
                        String path = uploadPath + "/" + name;
                        //创建输出文件对象
                        File outFile = new File(path);
                        //拷贝文件到输出文件对象
                        file.transferTo(outFile);

                        PBFile pbFile = new PBFile();
                        pbFile.setId(simpleUUID);
                        pbFile.setBaseInfo();
                        pbFile.setName(name);
                        pbFile.setPath(path);
                        pbFile.setHash(hash);

                        createPDF(path, fileName, outFile);

                        pbFileRepository.save(pbFile);

                        images.add("/files/" + name);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return images;
    }

    @Override
    public List<String> uploadFile(MultipartFile[] files) {
        List<String> ids = new ArrayList<>();

        //这里可以支持多文件上传
        if (files != null && files.length >= 1) {
            try {
                for (MultipartFile file : files) {

                    String id = uploadFile(file);
                    ids.add(id);

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ids;
    }

    @Override
    public String uploadFile(MultipartFile file) throws IOException {

        //验证文件是否已上传
        String hash = MD5Util.digestHex(file);
        PBFile byHash = pbFileRepository.findByHash(hash);
        if (byHash != null) {
            String id = byHash.getId();
            return id;
        }

        String fileName = file.getOriginalFilename();
        //判断是否有文件且是否为图片文件
        if(fileName!=null && !"".equalsIgnoreCase(fileName.trim())) {

            String simpleUUID = IdUtil.simpleUUID();

            File uploadDirectory = new File(uploadPath + "/" + simpleUUID);
            if (uploadDirectory.exists()) {
                if (!uploadDirectory.isDirectory()) {
                    uploadDirectory.delete();
                }
            } else {
                uploadDirectory.mkdir();
            }

            String path = uploadPath + "/" + simpleUUID + "/" + fileName;
            //创建输出文件对象
            File outFile = new File(path);
            //拷贝文件到输出文件对象
            file.transferTo(outFile);

            PBFile pbFile = new PBFile();
            pbFile.setId(simpleUUID);
            pbFile.setBaseInfo();
            pbFile.setName(fileName);
            pbFile.setPath(path);
            pbFile.setHash(hash);

            createPDF(path, fileName, outFile);

            pbFileRepository.save(pbFile);

            return simpleUUID;

        }


        return "";
    }


    /**
     * 在同级目录下生成pdf 预览使用
     * @param path 原始文件路径
     * @param fileName 原始文件名称
     * @param file 原始文件
     */
    public void createPDF(String path, String fileName,File file) {

        int indexOf = path.lastIndexOf("."); //直接在文件目录下生成pdf文件
        String newPath = path.substring(0, indexOf) + ".pdf";
        File newFile = FileUtil.file(newPath);
        fileName = fileName.toLowerCase();

        if (fileName.endsWith("doc") || fileName.endsWith("docx") ) {

            PDFUtil.word2PDF(file, newFile);

        } else if (fileName.endsWith("xls") || fileName.endsWith("xlsx") ) {

            PDFUtil.excel2PDF(file, newFile);
        }
    }

    @Override
    public PBFile get(String fileId) {

        Optional<PBFile> repository = fileRepository.findById(fileId);

        if (!repository.isPresent()) {
            throw new BaseException(Status.DATA_NOT_EXIST.getCode(), "未找到文件信息！");
        }
        PBFile pbFile = repository.get();

        return pbFile;
    }



    @Override
    public void download(HttpServletResponse response, String fileId) throws IOException {

        PBFile pbFile = get(fileId);
        Boolean isDownload = pbFile.getIsDownload();
        if (!isDownload) {
            throw new BaseException(Status.BAD_REQUEST.getCode(), "该文件不能下载！");
        }

        String path = pbFile.getPath();
        String fileName = pbFile.getName();

        logService.save("文件", fileName, OPERATION_DOWNLOAD);

        //response为HttpServletResponse对象
        response.setContentType("application/force-download");
        //        设置编码，避免文件名中文乱码
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1") );
        ServletOutputStream outputStream = response.getOutputStream();

        outputStream.write(FileUtil.readBytes(path));
        IoUtil.close(outputStream);

    }

    @Override
    public String preview(String fileId) {


        PBFile pbFile = get(fileId);
        String path = pbFile.getPath();
        int indexOf = path.lastIndexOf("."); //直接在文件目录下找pdf文件
        String newPath = path.substring(0, indexOf) + ".pdf";

        boolean exist = FileUtil.exist(newPath);
        if (!exist) {
            throw new BaseException(Status.ERROR.getCode(), "未找到该文件的预览文件！");
        }

        String replace = newPath.replace(uploadPath, "");

        return "/files" + replace;


    }

    @Override
    public PBFile updateIsDownload(String id, Boolean isDownload) {

        PBFile pbFile = get(id);
        pbFile.setIsDownload(isDownload);

        PBFile save = pbFileRepository.save(pbFile);

        return save;
    }

    private Boolean isImageFile(String fileName) {
        String[] img_type = new String[]{".jpg", ".jpeg", ".png", ".gif", ".bmp"};
        if (fileName == null) {
            return false;
        }
        fileName = fileName.toLowerCase();
        for (String type : img_type) {
            if (fileName.endsWith(type)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取文件后缀名
     *
     * @param fileName
     * @return
     */
    private String getFileType(String fileName) {
        if (fileName != null && fileName.indexOf(".") >= 0) {
            return fileName.substring(fileName.lastIndexOf("."), fileName.length());
        }
        return "";
    }


}
